package mya.mes.mdc.mongodb;

import com.mongodb.BasicDBList;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Sorts;
import com.sun.org.apache.xpath.internal.operations.Bool;
import mya.mes.mdc.local.mongodb.FilterDto;
import mya.mes.mdc.local.mongodb.MongoDbService;
import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.bson.conversions.Bson;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class MongoDbServiceImpl implements MongoDbService {
    @Override
    public void saveMdcData(Document doc) throws Exception {
        MongoDatabase database = DbManger.getInstance().getDatabase();
        MongoCollection coll = database.getCollection(DbCollections.MDC_DATA);
        coll.insertOne(doc);
    }

    @Override
    public void saveData(Document doc, String collectionName) throws Exception {
        MongoDatabase database = DbManger.getInstance().getDatabase();
        MongoCollection coll = database.getCollection(collectionName);
        coll.insertOne(doc);
    }

    @Override
    public List<Document> queryTagData(List<String> tagNoList, List<FilterDto> dtoList, String sortPropery) {

        MongoDatabase database = DbManger.getInstance().getDatabase();
        MongoCollection<Document> collection = database.getCollection(DbCollections.MDC_DATA);
        List<Document> list = new ArrayList<>();
        FindIterable<Document> dataCollection = null;
        //最终查询条件
        Bson finalBson = null;
        //tag过滤条件 查询包含tagNo的数据
        Bson tagBson = null;
        for (String tagNo : tagNoList) {
            Bson tgBson = Filters.exists(tagNo, true);
            if (tagBson != null) {
                tagBson = Filters.or(tagBson, tgBson);
            } else {
                tagBson = tgBson;
            }
        }

        //过滤条件的数据
        Bson filterBson = null;
        for (FilterDto dto : dtoList) {
            String properyName = dto.propertyName;
            String operator = dto.operator;
            Long longValue = dto.longValue;
            String value = dto.value;
            Bson field = null;
            switch (operator) {
                case "LT":
                    field = Filters.lt(properyName, longValue);
                    break;
                case "LE":
                    field = Filters.lte(properyName, longValue);
                    break;
                case "EQ":
                    field = Filters.eq(properyName, value);
                    break;
                case "GE":
                    field = Filters.gte(properyName, longValue);
                    break;
                case "GT":
                    field = Filters.gt(properyName, longValue);
                    break;
                case "NE":
                    field = Filters.ne(properyName, value);
                    break;
                case "IN":
                    field = Filters.in(properyName, value);
                    break;
                case "LK":
                    field = Filters.regex(properyName, "^.*" + value + ".*$", "i");
                    break;
            }
            if (field != null) {
                if (filterBson != null) {
                    filterBson = Filters.and(field, filterBson);
                } else {
                    filterBson = field;
                }
            }
        }
        if (tagBson != null) {
            finalBson = tagBson;
        }

        if (filterBson != null) {
            if (finalBson != null) {
                finalBson = Filters.and(finalBson, filterBson);
            } else {
                finalBson = filterBson;
            }
        }
        if (finalBson != null) {
            dataCollection = collection.find(finalBson);
        }
        if (dataCollection == null) {
            dataCollection = collection.find();
        }
        Consumer<Document> printBlock = new Consumer<Document>() {
            @Override
            public void accept(Document document) {
                list.add(document);
            }

        };

        if (dataCollection != null) {
            if (sortPropery != null) {
                dataCollection = dataCollection.sort(Sorts.ascending(sortPropery));
            }
            dataCollection.forEach(printBlock);
        }
        return list;
    }

    @Override
    public List<Document> queryMdcDataByParameter(String lineName, String dt, String topic, String sortPropery) {
        MongoDatabase database = DbManger.getInstance().getDatabase();
        MongoCollection<Document> collection = database.getCollection(DbCollections.MDC_DATA);
        List<Document> list = new ArrayList<>();
        Consumer<Document> printBlock = new Consumer<Document>() {
            @Override
            public void accept(Document document) {
                list.add(document);
            }
        };

        //过滤条件的数据
        Bson filterBson = null;
        if (StringUtils.isNotEmpty(lineName)) {
            filterBson = Filters.eq("lineName", lineName);
        }

        if (StringUtils.isNotEmpty(topic)) {
            if (filterBson != null) {
                Bson field = Filters.eq("topic", topic);
                filterBson = Filters.and(field, filterBson);
            }
        }

        if (StringUtils.isNotEmpty(dt)) {
            if (filterBson != null) {
                Bson field = Filters.regex("DT", "^.*" + dt + ".*$", "i");
                filterBson = Filters.and(field, filterBson);
            } else {
                filterBson = Filters.regex("DT", "^.*" + dt + ".*$", "i");
            }
        }

        FindIterable<Document> dataCollection = null;
        if (filterBson != null) {
            dataCollection = collection.find(filterBson);
        } else {
            dataCollection = collection.find();
        }

        if (dataCollection != null) {
            if (sortPropery != null) {
                dataCollection = dataCollection.sort(Sorts.ascending(sortPropery));
            }
            dataCollection.forEach(printBlock);
        }
        return list;
    }

    @Override
    public List<Document> queryMdcReportDataByParameter(String dt, String sortPropery) {
        MongoDatabase database = DbManger.getInstance().getDatabase();
        MongoCollection<Document> collection = database.getCollection(DbCollections.MDC_DATA);
        List<Document> list = new ArrayList<>();
        Consumer<Document> printBlock = new Consumer<Document>() {
            @Override
            public void accept(Document document) {
                list.add(document);
            }
        };

        //过滤条件的数据
        Bson filterBson = null;

        if (StringUtils.isNotEmpty(dt)) {
            if (filterBson != null) {
                Bson field = Filters.regex("DT", "^.*" + dt + ".*$", "i");
                filterBson = Filters.and(field, filterBson);
            } else {
                filterBson = Filters.regex("DT", "^.*" + dt + ".*$", "i");
            }
        }

        FindIterable<Document> dataCollection = null;
        if (filterBson != null) {
            dataCollection = collection.find(filterBson);
        } else {
            dataCollection = collection.find();
        }

        if (dataCollection != null) {
            if (sortPropery != null) {
                dataCollection = dataCollection.sort(Sorts.ascending(sortPropery));
            }
            dataCollection.forEach(printBlock);
        }
        return list;
    }

    @Override
    public List<Document> queryMdcData(List<FilterDto> filterDtoList, String sortPropery) throws Exception {

        MongoDatabase database = DbManger.getInstance().getDatabase();
        MongoCollection<Document> collection = database.getCollection(DbCollections.MDC_DATA);
        List<Document> list = new ArrayList<>();
        Consumer<Document> printBlock = new Consumer<Document>() {
            @Override
            public void accept(Document document) {
                list.add(document);
            }
        };

        FindIterable<Document> dataCollection = null;
        if (filterDtoList != null && filterDtoList.size() > 0) {
            for (FilterDto dto : filterDtoList) {
                String properyName = dto.propertyName;
                Object value = dto.value;
                Bson field = Filters.regex(properyName, "^.*" + value + ".*$", "i");
                if (dataCollection != null) {
                    dataCollection.filter(field);
                } else {
                    dataCollection = collection.find(field);
                }
            }
        } else {
            if (dataCollection == null) {
                dataCollection = collection.find();
            }
        }

        if (dataCollection != null) {
            if (sortPropery != null) {
                dataCollection = dataCollection.sort(Sorts.ascending(sortPropery));
            }
            dataCollection.forEach(printBlock);
        }
        return list;
    }
}
